;; cedet configuration
;; from https://github.com/alexott/emacs-configs/blob/master/rc/emacs-rc-cedet-new.el, thanks to Alex Ott

(require 'cedet)
(setq semantic-default-submodes '(global-semantic-idle-scheduler-mode
				  global-semanticdb-minor-mode
				  global-semantic-idle-summary-mode
				  global-semantic-mru-bookmark-mode
				  global-semantic-decoration-mode
				  global-semantic-highlight-edits-mode
				  ))

;; Activate semantic
(semantic-mode 1)
(global-semantic-highlight-edits-mode (if window-system 1 -1))
(global-semantic-show-unmatched-syntax-mode)
(global-semantic-show-parser-state-mode)
(global-semantic-idle-local-symbol-highlight-mode)

(require 'semantic/analyze/refs)
(require 'semantic/bovine/c)
(require 'semantic/bovine/gcc)
(require 'semantic/bovine/el)
(require 'semantic/ia)
(require 'semantic/decorate/include)
(require 'semantic/lex-spp)

(defun alexott/cedet-hook ()
  ;;  (local-set-key [(control return)] 'semantic-ia-complete-symbol-menu)
  (local-set-key "\C-c?" 'semantic-ia-complete-symbol)
  ;;
  (local-set-key "\C-c>" 'semantic-complete-analyze-inline)
  (local-set-key "\C-c=" 'semantic-decoration-include-visit)

  (local-set-key "\C-cj" 'semantic-ia-fast-jump)
  (local-set-key "\C-cq" 'semantic-ia-show-doc)
  (local-set-key "\C-cs" 'semantic-ia-show-summary)
  (local-set-key "\C-cp" 'semantic-analyze-proto-impl-toggle)
  )
;; (add-hook 'semantic-init-hooks 'alexott/cedet-hook)
(add-hook 'c-mode-common-hook 'alexott/cedet-hook)
(add-hook 'lisp-mode-hook 'alexott/cedet-hook)
(add-hook 'scheme-mode-hook 'alexott/cedet-hook)
(add-hook 'emacs-lisp-mode-hook 'alexott/cedet-hook)

(require 'eassist)
(defun alexott/c-mode-cedet-hook ()
  ;; (local-set-key "." 'semantic-complete-self-insert)
  ;; (local-set-key ">" 'semantic-complete-self-insert)
  (local-set-key "\C-ct" 'eassist-switch-h-cpp)
  (local-set-key "\C-xt" 'eassist-switch-h-cpp)
  (local-set-key "\C-ce" 'eassist-list-methods)
  (local-set-key "\C-c\C-r" 'semantic-symref)
  )
(add-hook 'c-mode-common-hook 'alexott/c-mode-cedet-hook)

;; setup compile package
;; TODO: allow to specify function as compile-command
(require 'compile)
(setq compilation-disable-input nil)
(setq compilation-scroll-output t)
(setq mode-compile-always-save-buffer-p t)

(defun alexott/ede-get-local-var (fname var)
  "fetch given variable var from :local-variables of project of file fname"
  (let* ((current-dir (file-name-directory fname))
	 (prj (ede-current-project current-dir)))
    (when prj
      (let* ((ov (oref prj local-variables))
	     (lst (assoc var ov)))
	(when lst
	  (cdr lst))))))

(defun alexott/compile ()
  "Saves all unsaved buffers, and runs 'compile'."
  (interactive)
  (save-some-buffers t)
  (let* ((r (alexott/ede-get-local-var
	     (or (buffer-file-name (current-buffer)) default-directory)
	     'compile-command))
	 (cmd (if (functionp r) (funcall r) r)))
    ;;    (message "AA: %s" cmd)
    (set (make-local-variable 'compile-command) (or cmd compile-command))
    (compile compile-command)))
(global-set-key [f7] 'alexott/compile)

;;
(defun alexott/gen-std-compile-string ()
  "Generates compile string for compiling CMake project in debug mode"
  (let* ((current-dir (file-name-directory
		       (or (buffer-file-name (current-buffer)) default-directory)))
	 (prj (ede-current-project current-dir))
	 (root-dir (ede-project-root-directory prj))
	 )
    (concat "cd " root-dir "; make -j4")))

;;
(defun alexott/gen-cmake-debug-compile-string ()
  "Generates compile string for compiling CMake project in debug mode"
  (let* ((current-dir (file-name-directory
		       (or (buffer-file-name (current-buffer)) default-directory)))
	 (prj (ede-current-project current-dir))
	 (root-dir (ede-project-root-directory prj))
	 (subdir "")
	 )
    (when (string-match root-dir current-dir)
      (setf subdir (substring current-dir (match-end 0))))
    (concat "cd " root-dir "Debug/" "; make -j3")))

(defadvice push-mark (around semantic-mru-bookmark activate)
  "Push a mark at LOCATION with NOMSG and ACTIVATE passed to `push-mark'.
If `semantic-mru-bookmark-mode' is active, also push a tag onto
the mru bookmark stack."
  (semantic-mrub-push semantic-mru-bookmark-ring
		      (point)
		      'mark)
  ad-do-it)

;; includes
(defconst user-include-dirs
  (list "." ".." "../include" "../inc" "../common" "../public"
	"../.." "../../include" "../../inc" "../../common" "../../public"))
(defconst linux-include-dirs
  (list "/usr/include"
	"/usr/include/c++/4.7.0/"
	"/usr/include/c++/4.7.0/backward/"
	"/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/include/"
	"/usr/local/include"
	))
(defconst turf-include-dirs
  (list "/ssh:supertool@53.mzhen.cn:/home/workspace/wujian/Turf/"
	"/ssh:supertool@53.mzhen.cn:/home/workspace/wujian/Turf/src/common/"
	"/ssh:supertool@53.mzhen.cn:/home/workspace/wujian/Turf/src/dicmanager/"))
(let ((include-dirs user-include-dirs))
  (setq include-dirs (append include-dirs linux-include-dirs turf-include-dirs))
  (mapc (lambda (dir)
	  (semantic-add-system-include dir 'c++-mode)
	  (semantic-add-system-include dir 'c-mode))
	include-dirs))

(provide 'jerry-cedet)
